package com.wang.learn.common.utils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * @author : wcz
 * @version V1.0
 * @Description: 并发查库工具类
 * @date Date : 2021年10月29日 13:22
 */
@Deprecated
public class DataQueryUtil {

    private ThreadPoolExecutor threadPoolExecutor;

    private DataQueryUtil(ThreadPoolExecutor threadPoolExecutor){
        this.threadPoolExecutor = threadPoolExecutor;
    }

    public static DataQueryUtil getInstance(ThreadPoolExecutor executor){
        return new DataQueryUtil(executor);
    }

    /**
     * 并发查库
     * @param fn 要传入的方法，
     * @param <T> 对象类型
     * @return 返回List<T>
     */
    public <T> CompletableFuture<List<T>> queryList(Supplier<List<T>> fn){
        return CompletableFuture.supplyAsync(()->fn.get(),threadPoolExecutor);
    }

    /**
     *
     * @param fn 数据的查询f方法
     * @param kfn 获取Id的方法
     * @param <T>
     * @return Map<Id,T> </>
     */
    public <T> CompletableFuture<Map<Number,T>> queryMap(Supplier<List<T>> fn,Function<T,Number>kfn){
        return CompletableFuture.supplyAsync(()->{
            List<T> ts = fn.get();
            Stream<T> stream = ts == null ? Stream.empty() : ts.stream();
            return stream.collect(Collectors.toMap(kfn,Function.identity()));
        },threadPoolExecutor);
    }



    public <T> T getData(CompletableFuture<T> future){
        return getData(future,1,TimeUnit.SECONDS);
    }
    public <T> T getData(CompletableFuture<T> future, Number no){
        return getData(future,no,TimeUnit.SECONDS);
    }
    public <T> T getData(CompletableFuture<T> future, Number no, TimeUnit unit){
        Exception exception = null;
        try {
            T t = future.get(no.longValue(),unit);
            return t;
        } catch (InterruptedException e) {
            exception=e;
        } catch (ExecutionException e) {
            exception=e;
        } catch (TimeoutException e) {
            exception=e;
        }
        throw new RuntimeException(exception);
    }

}
